{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     sepallength  sepalwidth  petallength  petalwidth            class\n",
      "82           5.8         2.7          3.9         1.2  Iris-versicolor\n",
      "113          5.7         2.5          5.0         2.0   Iris-virginica\n",
      "53           5.5         2.3          4.0         1.3  Iris-versicolor\n",
      "62           6.0         2.2          4.0         1.0  Iris-versicolor\n",
      "43           5.0         3.5          1.6         0.6      Iris-setosa\n",
      "72           6.3         2.5          4.9         1.5  Iris-versicolor\n",
      "2            4.7         3.2          1.3         0.2      Iris-setosa\n",
      "99           5.7         2.8          4.1         1.3  Iris-versicolor\n",
      "148          6.2         3.4          5.4         2.3   Iris-virginica\n",
      "20           5.4         3.4          1.7         0.2      Iris-setosa\n",
      "150\n",
      "147\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0    50\n",
       "2    49\n",
       "1    48\n",
       "Name: class, dtype: int64"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_csv(r\"dataset/iris.arff.csv\", header=0)\n",
    "# data.head(10)\n",
    "# data.tail(10)\n",
    "print(data.sample(10))\n",
    "data[\"class\"] = data[\"class\"].map({\"Iris-versicolor\":0,\"Iris-setosa\":1,\"Iris-virginica\":2}) # 类别名称映射为数字\n",
    "# data = data.drop(\"Id\",axis=1)  # 删除列\n",
    "print(len(data))\n",
    "if data.duplicated().any(): # 重复值\n",
    "    data.drop_duplicates(inplace=True) #删除重复值\n",
    "    print(len(data))\n",
    "data[\"class\"].value_counts()  # 查看各个类别的鸢尾花记录\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [],
   "source": [
    "class KNN:\n",
    "    '''使用KNN实现K近邻算法实现分类'''\n",
    "    def __init__(self, k):\n",
    "        '''初始化\n",
    "        \n",
    "        Parameters\n",
    "        -----\n",
    "        k:int\n",
    "            邻居个位数\n",
    "        \n",
    "        '''\n",
    "        self.k = k\n",
    "    def fit(self, X, y):\n",
    "        '''训练\n",
    "        \n",
    "        Parameeters\n",
    "        -----\n",
    "        X: 类数组类型，可以是List也可以是Ndarray，形状为： [样本数量,特征数量]\n",
    "        y: ；类数组类型，形状为：[样本数量]\n",
    "        \n",
    "        '''\n",
    "        self.X = np.asarray(X) #转换为ndarray类型\n",
    "        self.y = np.asarray(y)\n",
    "    def predict(self, X):\n",
    "        '''对样本进行预测\n",
    "        Parameters:\n",
    "        X: 类数组类型，可以是List也可以是Ndarray，形状为： [样本数量,特征数量]\n",
    "        Returns:\n",
    "        数组类型，预测结果\n",
    "        '''\n",
    "        X = np.asarray(X)\n",
    "        result = []\n",
    "        for x in X:\n",
    "            dis = np.sqrt(np.sum((x-self.X)**2, axis=1)) # 对于测试机的每隔一个样本，一次与训练集的所有数据求欧氏距离\n",
    "            index = dis.argsort()# 返回排序结果的下标\n",
    "            index = index[:self.k] # 截取前K个\n",
    "            count = np.bincount(self.y[index]) # 返回数组中每个整数元素出现次数，元素必须是非负整数\n",
    "            result.append(count.argmax()) # 返回ndarray中值最大的元素所对应的索引，就是出现次数最多的索引，也就是我们判定的类别\n",
    "        return np.asarray(result)\n",
    "    def predict(self, X):\n",
    "        '''对样本进行预测，加入权重计算\n",
    "        Parameters:\n",
    "        X: 类数组类型，可以是List也可以是Ndarray，形状为： [样本数量,特征数量]\n",
    "        Returns:\n",
    "        数组类型，预测结果\n",
    "        '''\n",
    "        X = np.asarray(X)\n",
    "        result = []\n",
    "        for x in X:\n",
    "            dis = np.sqrt(np.sum((x-self.X)**2, axis=1)) # 对于测试机的每隔一个样本，一次与训练集的所有数据求欧氏距离\n",
    "            index = dis.argsort()# 返回排序结果的下标\n",
    "            index = index[:self.k] # 截取前K个\n",
    "            count = np.bincount(self.y[index], weights=1/dis[index]) # 返回数组中每个整数元素出现次数，元素必须是非负整数\n",
    "            result.append(count.argmax()) # 返回ndarray中值最大的元素所对应的索引，就是出现次数最多的索引，也就是我们判定的类别\n",
    "        return np.asarray(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# 提取每个类中鸢尾花数据\n",
    "t0 = data[data[\"class\"]==0]\n",
    "t1 = data[data[\"class\"]==1]\n",
    "t2 = data[data[\"class\"]==2]\n",
    "# 打乱# 打乱每个类别数据\n",
    "t0 = t0.sample(len(t0), random_state=0)\n",
    "t1 = t1.sample(len(t1), random_state=0)\n",
    "t2 = t2.sample(len(t2), random_state=0)\n",
    "# 分配训练集和数据集，axis=0表示按纵向方式拼接\n",
    "train_X = pd.concat([t0.iloc[:40, :-1], t1.iloc[:40, :-1], t2.iloc[:40, :-1]], axis=0)\n",
    "train_y = pd.concat([t0.iloc[:40, -1], t1.iloc[:40, -1], t2.iloc[:40, -1]], axis=0)\n",
    "test_X = pd.concat([t0.iloc[40:, :-1], t1.iloc[40:, :-1], t2.iloc[40:, :-1]], axis=0)\n",
    "test_y = pd.concat([t0.iloc[40:, -1], t1.iloc[40:, -1], t2.iloc[40:, -1]], axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9629629629629629"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "knn = KNN(k=3)\n",
    "knn.fit(X=train_X, y=train_y)\n",
    "result = knn.predict(test_X)\n",
    "# display(result)\n",
    "# display(test_y)\n",
    "display(np.sum(result==test_y)/len(result))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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B2cMFZrsfgAAAAAAoH6Yc668HZj9naT/6ZzbNt4+bW1tbtu2/G+//PLLOvXUU8s6NpQHrx0AAAAAANVnZtudc4fNHinrMjEzi0v60FiJIDNLm9k2M9v2+uuvl3MYAAAAAAAAGFXumkE3SFo31jeccxnnXJtzru2EE04o8zAAAAAAAAAglTEZZGYRSZ+WtLFcfQAAAAAAAKA45ZwZdIGkX7lyFyUCAAAAAADApJUzGXSJpE1lPD4AAAAAAACKVLZkkHPuFufc98t1/ELBrwMlVycV+euIkquTCn4dlOS4LS0tk9pv+fLlJelvPM8995yee+65svYBAAAAAEChIJCSSSkS8dugNB+3UUXRag+gFIJfB0r/S1pD7w9Jkvp/36/0v6QlSanTUhUZw+rVq8t6/Gwi6PTTTy9rPwAAAAAAZAWBlE5LQ/7jtvr7fVuSUpX5uI0yKPfTxCqi6+ddBxNBWUPvD6nr510l76ujo0M33XSTLrnkksPiWfv27dOiRYvU3t6uyy67TMPDw2Mea6z9hoaGtGTJErW3t+uGG26QJP3VX/2VvvWtb+lb3/qWPvOZz0iS3nvvPX35y1/WwoULlUqltH///jGPt3fvXl166aW64IILdM0115T8egAAAAAAwqur61AiKGtoyMdRv0KRDBr4/UBR8enYunWrzjnnHG3YsGHcfXbs2KFIJKJNmzbpmmuu0d69e3Xdddepo6Pj4J/bbrttzP0ymYxaW1u1adMm7dq1Sy+88ILuuOMO3Xzzzbr55pv185//XJK0fv16tba26oknntDcuXN13333jXm8Xbt26cYbb9TPfvYz9fX16be//W3JrwkAAAAAIJwGxvlYPV4c9SEUy8QSxyXU//v+MeOl1traqsWLFx9xnwULFqi1tVUXX3yx5s6dq0svvVR33333Yfs55w7b79VXX9WTTz6pjRs3as+ePRocHNQnPvGJw352x44dB8dx9tln65FHHtF111132PFmzJihe+65R/fff7/efPNN7du3rzQXAgAAAAAQeomEXxo2Vhz1KxQzg7o/063YjFheLDYjpu7PdJe8r1mzZk24z/PPP6/zzjtPjz32mN566y1t3rx50vt97GMf0/Lly7Vx40Z985vfVGL0HXbsscdqaHRunnNO8+bN09atWyX52Urz5s0b83j33nuvlixZogcffFAzZ84s0VUAAAAAADSC7m4plv9xW7GYj6N+hSIZlDotpcwXM2o+rlkmU/Nxzcp8MVOx4tGFksmk7rzzTp177rnavXu32traJr3f0qVL9cgjj6i9vV133XWXPvzhD0uSLrroIn3/+9/Xeeedp82bN+vaa6/VSy+9pPb2dr322mu6+uqrxzzeRRddpDvuuEMXXnihJGlwcLBi1wEAAAAAUN9SKSmTkZqbJTO/zWQoHl3vzDlX7TGora3Nbdu2LS/28ssv69RTT63SiDAdvHYAAAAAAFSfmW13zh02QyUUM4MAAAAAAAAwOSSDAAAAAAAAGgjJIAAAAAAAgAZCMggAAAAAAKCBkAwCAAAAAABoIKFJBgWBlExKkYjfBkFpjtvS0jKp/ZYvX16aDktwvMn+bKnHDAAAAAAAal8oHi0fBFI6LQ0NHYrFYlImI6VS0xtbS0uLenp6pneQBsOj5QEAAAAAqL5QP1q+qys/EST5dldX6fvq6OjQTTfdpEsuueSweNa+ffu0aNEitbe367LLLtPw8PCYx+ru7tYPf/hDSdIdd9yhhx56aMzjjdXvvn379LnPfU5nnXWW/uzP/ky33377mD+7cuVKdXV1qb29Xaeffrp279495n7vvvuurrzySp1//vlatGiRhoaGtHfvXl166aW64IILdM0110zq+gAAAAAAgNoWimTQwEBx8enYunWrzjnnHG3YsGHcfXbs2KFIJKJNmzbpmmuu0d69e3Xdddepo6Pj4J/bbrtNV1xxhR555BFJ0qZNm/T5z39+0v2+8sormjNnjrZs2aKenh7dcsst4/5sT0+PNm3apMWLF+vxxx8fc59MJqNPfvKT2rJliy6//HK9+OKL2rVrl2688Ub97Gc/U19fn377299O5hIBAAAAAIAaFq32AEohkZD6+8eOl1pra6sWL158xH0WLFig1tZWXXzxxZo7d64uvfRS3X333WPuu3PnTr399tuaPXu2Zs6cOel+4/G4tm/frvb2dnV2dh5xPFdddZUkKZFIaP/+/WPu88orr+jyyy+XJF199dWSpP7+ft1zzz26//779eabb2rfvn1H7AcAAAAAED7LlvkyLAcOSE1NvkzL2rXVHhWmIxQzg7q7fY2gXLGYj5farFmzJtzn+eef13nnnafHHntMb731ljZv3jzuvmeeeaZWr16tL33pS0X1++ijj+rWW2/VU089pdQEhZGOlGTKOuWUU/T0009Lkm6//Xbdc889uvfee7VkyRI9+OCDkzoGAAAAACBcli2T1q3ziSDJb9et83HUr1Akg1Ipn6VsbpbM/LYUxaOnKplM6s4779S5556r3bt3q63tsFpNB11xxRVavXq1Fi1aVFQf8+fP14033qgLL7xQV155pV588cVpjXnp0qV65pln1NHRoWeeeUZf+cpXdNFFF+mOO+7QhRdeKEkaHBycVh8AAAAAgPqSyRQXR30IxdPEGtH69ev14IMPasaMGZoxY4a+9rWvHVZ0ulp47QAAAAAgHMzG/14NpBMwgfGeJhaKmkGNaOnSpVq6dGm1hwEAAAAACLGmpkNLxArjqF+hWCYGAAAAAABKL50uLo76wMwgAAAAAAAwpuxTw3iaWLiQDAIAAAAAAONau5bkT9iEZplYYSHsWiiMDQAAAABAqQWBlExKkYjfBkG1R4R6E4pk0MreXq3o6TmYAHLOaUVPj1b29palv+XLlx95PCtXauPGjYfFn3vuOT333HNlGRMAAAAAIPyCwC/T6u/3T/Pq7/dtEkIoRt0ng5xz2jM8rDWDgwcTQit6erRmcFB7hofLMkNo9erVU/o5kkEAAAAAgOno6pKGhvJjQ0M+DkxW3dcMMjOtammRJK0ZHNSawUFJUmc8rlUtLTKzKR+7o6NDn/rUp/TCCy9ow4YNefHszJ99+/Zp8eLFevPNN/XRj35Ura2tkqSf/vSn+vrXv663335bjz76qNasWaMf/OAHkqTvfe97+vnPfz7lcQEAAAAAGtPAQHFxYCx1PzNIyk8IZU03ESRJW7du1TnnnJOXCCr0yiuvaM6cOdqyZYt6enp0yy23SJJ6enq0adMmLV68WI8//rjuuOMO3Xzzzbr55ptJBAEAAAAApiSRKC4OjCUUyaDs0rBcuTWEpqq1tVWLFy8+4j7xeFzbt29Xe3u7Ojs7D8avuuoqSVIikdD+/funNQ4AAAAAACSpu1uKxfJjsZiPA5NV98vEcmsEZZeGZdvS9GYIzZo1a8J9Hn30Ud1666267LLL8uIzZ848bN9jjz1Wb7zxxsFxT3fmEgAAAACgsaRSftvV5ZeGJRI+EZSNA5NR9zODzEyzo9G8GkGrWlrUGY9rdjRa9oTL/PnzdeONN+rCCy/UlVdeqRdffHHcfS+66CJ9//vf13nnnafNmzeXdVwAAAAAgHBKpaS+PmlkxG9JBKFYVo6nbRWrra3Nbdu2LS/28ssv69RTT530MQpn2lRq5s369ev14IMPasaMGZoxY4a+9rWvqaOjo+z91rJiXzsAAAAAAFB6ZrbdOddWGK/7ZWJZhYmfSi3BWrp0qZYuXVqRvgAAAAAAAKar7peJAQAAAAAAYPJIBgEAAAAAADQQkkEAAAAAAAANhGQQAAAAAABAAwlFMujJOU/q1WWv6r1d71V7KAAAAAAAADUtFMmg/YP7tfve3frVSb8iKQQAAAAAAHAEoXm0vNvv5OS0+97d+u39v9WHrvmQkrcmdfSJR0/peG1tbfrJT36i0047Tc8995y++tWvamhoSJ/61Kf0wgsvaMOGDXrvvfd09dVX6ze/+Y3mzJmj+++/X7fffrvef/99bd68WW+//bYeffRRHXfccVq8eLHefPNNffSjH1Vra6tuueWWEl8BAAAAAACAiYViZlAut99p5N0R7bp7l549/9kpH+ekk07Shg0bdOaZZ+qxxx7TggULtHXrVp1zzjnasGGDJGn9+vVqbW3VE088oblz5+q+++6TJPX09GjTpk1avHixHn/8cb3yyiuaM2eOtmzZop6eHhJBAAAAAADUiCCQkkkpEvHbIKj2iMovdMkgO8oUOTaiP/6LP9b8X86f8nEWLFigf/zHf9QXvvAFPfTQQzrjjDPU2tqqxYsXH9xnx44dOuussyRJZ599tl5++WVJ0lVXXSVJSiQS2r9/v+LxuLZv36729nZ1dnZO4+wAAAAAAECpBIGUTkv9/ZJzfptOhz8hFJpkUDYJdOK1J+qsfz1LJ3/3ZB39R1NbIiZJ8+fP1+OPP67Pfvaz2rBhgxYsWKBZs2bl7TNv3jxt3bpVkrR161bNmzdPkjRz5sy8/R599FHdeuuteuqpp5RKpaY8JgAAAAAAUDpdXdLQUH5saMjHwywUyaCj4keVLAmUtWDBAjU3N+ukk07SH/7hH6q5ufmwfa699lq99NJLam9v12uvvaarr756zGPNnz9fN954oy688EJdeeWVevHFF6c9PgAAAAAAMD0DA8XFwyIUBaTP3XluyY95wgknaMeOHZKkwcFBSdLGjRvz9jn66KP14IMP5sVWrlx58Otscmj9+vU6+eSTNWPGDO3du1e/+93vSj5eAAAAAABQnETCLw0bKx5moUgG1bqlS5dq6dKl1R4GAAAAAADI0d3tawTlLhWLxXw8zGp6mZhzrtpDQJF4zQAAAAAA9SKVkjIZqblZMvPbTMbHw6xmZwYdc8wxeuONN3T88cfLzKo9HEyCc05vvPGGjjnmmGoPBQAAAACASUmlwp/8KVSzyaA5c+Zo586dev3116s9FBThmGOO0Zw5c6o9DAAAAAA1Igj8k5kGBnwdlu7uxvvgDdSamk0GzZgxQx/5yEeqPQwAAAAAwBQFQX49lv5+35ZICAHVVNM1gwAAAAAA9aurK78wr+TbXV3VGQ8Aj2QQAAAAAKAsBgaKiwOoDJJBAAAAAICySCSKiwOoDJJBAAAAAICy6O6WYrH8WCzm4wCqh2QQAAAAAKAsUikpk5GamyUzv81kKB4NVFvNPk0MAAAAAFD/UimSP0CtYWYQAAAAAABAAyEZBAAAAAAA0EBIBgEAAAAAADQQkkEAAAAAAAANhGQQAAAAAABAAyEZBAAAAAAA0EBIBgEAAAAAADQQkkEAAAAAAAANhGQQAAAAADQQ59wR2wDCj2QQAAAAADSIlb29WtHTczAB5JzTip4ereztrfLISisIpGRSikT8NgiqPaL6xvUMH5JBAAAAANAAnHPaMzysNYODBxNCK3p6tGZwUHuGh0MzQygIpHRa6u+XnPPbdJoExlRxPcPJauEN39bW5rZt21btYQAAAABAqOUmgLI643GtammRmVVxZKWTTPqERaHmZqmvr9KjqX9cz/pmZtudc22FcWYGAQAAAECDMDOtamnJi4UpESRJAwPFxXFkXM9wIhkEAAAAAA0iOzMoV24NoTBIJIqL48i4nuFEMggAAAAAGkDuErHOeFwjCxeqMx7PqyEUBt3dUiyWH4vFfBzF43qGU7TaAwAAAAAAlJ+ZaXY0mlcjKLtkbHY0GpqlYqmU33Z1+aVMiYRPXGTjKA7XM5woIA0AAAA55/I+CBa2AYQH73egcVBAGgAAAGNa2dubt0Qku5RkZW9vlUcGoBweeMCUTEqRiH9S1AMPkAgCGk1Zk0FmttbMvljOPgAAADB1zjntGR7OqxmSrSmyZ3g4NDVEAHhBIKXT/lHhzvltOu3jABpH2ZaJmdkFklY45xZPtC/LxAAAAKonNwGUlVtTBEB4JJM+AVSouVnq66v0aACUW0WXiZnZDEnrJfWZ2Z+Ms0/azLaZ2bbXX3+9HMMAAADAJOQWkc0iEQSE08BAcXEA4VSuZWJXSdoh6duSzjSzGwt3cM5lnHNtzrm2E044oUzDAAAAwESyM4Nyhekx0wAOSSSKiwMIp3Ilg+ZLyjjndkv6B0mfLlM/AAAAmIbcJWKd8bhGFi5UZzyeV0MIQHh0d0uxWH4sFvNxAI0jWqbj9kg6afTrNkljrEoFAABAtZmZZkejeTWCskvGZkejLBUDQiaV8tuuLr80LJHwiaBsHEBjKEsBaTP7gKT7JH1I0gxJS5xzg+PtTwFpAACA6nLO5SV+CtsAAKD+jFdAuiwzg5xz/y7pinIcGwAAAKVXmPghEQQAQHiVq2YQAAAAgJAKAv+I8kjEb4Og2iOqb1xPAJVWrppBAAAAAEIoCKR0Whoa8u3+ft+WqDszFVxPANVQlppBxaJmEAAAAFAfkkmfsCjU3Cz19VV6NPWP6wmgnMarGcQyMQAAAACTNjBQXBxHxvUEUA0kgwAAAABMWiJRXBxHxvUEUA0kgwAAAABMWne3FIvlx2IxH0fxuJ4AqoFkEAAAAIBJS6WkTMbXtDHz20yGYsdTxfUEUA0UkAYAAAAAAAghCkgDAACgYQWBf2pTJOK3QVDtEZVW2M8PpcX9AiBa7QEAAAAA5RQEUjotDQ35dn+/b0vhWIoT9vNDaXG/AJBYJgYAAICQSyb9B95Czc1SX1+lR1N6YT8/lBb3C9BYWCYGAACAhjQwUFy83oT9/FBa3C8AJJJBAAAACLlEorh4vQn7+aG0uF8ASCSDAAAAEHLd3VIslh+LxXw8DMJ+figt7hcAEskgAAAAhFwqJWUyviaKmd9mMuEplhv280Npcb8AkCggDQAAAAAAEEoUkAYAAABCatkyKRr1Mz2iUd8OkyDwT8GKRPw2CKo9IgCob9FqDwAAAADA1C1bJq1bd6h94MCh9tq11RlTKQWBlE5LQ0O+3d/v2xJLmwBgqlgmBgAAANSxaNQngAo1NUnDw5UfT6klkz4BVKi5Werrq/RoAKC+sEwMAAAACKGxEkFHitebgYHi4gCAiZEMAgAAAOpYU1Nx8XqTSBQXBwBMjGQQAAAAUMey9XMmG6833d1SLJYfi8V8HAAwNSSDAAAAgDq2dq10/fWHZgI1Nfl2GIpHS75IdCbjawSZ+W0mQ/FoAJgOCkgDAAAAAACEEAWkAQAAMK7CXxDWwi8MAQBAeZAMAgAAmIQg8I+4jkT8NgiqPaLSWdnbq8/9uEfNSadIRGpOOn3uxz1a2dtbtj6XLfOPRDfz22XLytZVQwjz/QkAKL1otQcAAABQ64LAF+MdGvLt/v5DxXnrvW6Jc05bXxrWhlmD0iJJ323RwKIeDcwalF6KyyWdzKykfS5bJq1bd6h94MChdljq3FRSmO9PAEB5UDMIAABgAsmk/4BdqLlZ6uur9GhKrznpNLCoR1oyeCj4cFyJH7Wov6+0iSDJzwQ6cODweFOTNDxc8u5CL+z3JwBg6qgZBAAAMEUDA8XF682/DZj03Zb84HdbfLwMxvVyUQgAACAASURBVEoEHSmOIwv7/QkAKD2SQQAAABNIJIqL15sPJ5x0Q09+8IYeHy+D7CPQJxvHkYX9/gQAlB7JIAAAgAl0d0uxWH4sFvPxeuec06nfGV0i9nBc+vRCv10yqFO/01OWp4pl69lMNo4jC/P9CQAoD5JBAAAAE0ilpEzG12Ax89tMJhzFec1MZ8+L6pK9vkaQmSnxoxZdsjeus+dFS148WvJFoq+//tBMoKYm36Z49NSE+f4EAJQHBaQBAAAg5/KfGlbYBgAA9YcC0gAAABhXYeKn3ImgIPBPwYpE/DYIytpdxfsLO64nANS3aLUHAAAAgMYSBL4+0NCQb/f3H6oXVI6lTZXuL+y4ngBQ/1gmBgAAgIpKJn0CoVBzs9TXV//9hR3XEwDqB8vEAAAAUBMGBoqL11t/Ycf1BID6RzIIAAAAFZVIFBevt/7CjusJAPWPZBAAAAAqqrtbisXyY7GYj4ehv7DjegJA/SMZBAAAgIpKpaRMxteYMfPbTKZ8xYcr3V/YcT0BoP5RQBoAAKAGOefyHu9e2AYaCe8HAJgaCkgDAADUiZW9vVrR06PsL+2cc1rR06OVvb1VHhlQebwfAKD0SAYBAADUEOec9gwPa83g4MEPwCt6erRmcFB7hodVC7O6gUrh/QAA5RGt9gAAAABwiJlpVUuLJGnN4KDWDA5Kkjrjca1qaWFpDBoK7wcAKA9mBgEAANSY3A/AWXzwRaPi/QAApUcyCAAAoMZkl8Lkyq2ZAjQS3g8AUHokgwAAAGpIbk2UznhcIwsXqjMez6uZAjQK3g8AUB7UDAIAAKghZqbZ0WheTZTsEpnZ0ShLY9BQeD8AQHlYLWTT29ra3LZt26o9DAAAgJrhnMv7oFvYBhoJ7wcAmBoz2+6cayuMs0wMAACgBhV+0OWDLxoZ7wcAKC2SQQAAAKi4ZcukaFQy89tly6o9IgAAGgc1gwAAAFBRy5ZJ69Ydah84cKi9dm11xgQAQCNhZhAAAAAqKpMpLg4AAEqLZBAAAAAq6sCB4uIAAKC0SAYBAACgopqaiosDAIDSIhkEAACAikqni4sDAIDSooA0AAAAKipbJDqT8UvDmpp8Ioji0QAAVAbJIAAAAFTc2rUkf0rJOSczG7cNAEAulokBAAAg9IJASialSMRvg6DaIyqdlb29WtHTI+ecJJ8IWtHTo5W9vVUeGQCgVpEMAgAAQKgFgV+G1t8vOee36XQ4EkLOOe0ZHtaawcGDCaEVPT1aMzioPcPDBxNEAADkslr4B6Ktrc1t27at2sMAAABACCWTPgFUqLlZ6uur9GhKLzcBlNUZj2tVSwtLxQCgwZnZdudcW2GcmUEAAAAItYGB4uL1xsy0qqUlL0YiCABwJCSDAAAAEGqJRHHxepOdGZQrt4YQAACFSAYBAAAg1Lq7pVgsPxaL+Xi9y10i1hmPa2ThQnXG43k1hAAAKMSj5QEAABBqqZTfdnX5pWGJhE8EZeP1zMw0OxrNqxGUXTI2OxplqRgAYEwUkAYAAADqnHMuL/FT2AYANCYKSAMA0ECWLZOiUcnMb5ctK29/QeCf2BSJ+G3ZH9ld8Q7DL+yXNOznV5j4CVsiKOyvHwBUGsvEAAAImWXLpHXrDrUPHDjUXru29P0FgZROS0NDvt3f79tSmZbhVLzD8Av7JQ37+YUdrx8AlB7LxAAACJlo1CeACjU1ScPDpe8vmfQfzgo1N0t9faXvr/Idhl/YL2nYzy/seP0AYOrGWyZGMggAgJA50uqQcvyzH4mMfVwzaWSk9P1VvsPwC/slDfv5hR2vHwBMHTWDAABoEE1NxcWnK5EoLl5/HYZf2C9p2M8v7Hj9AKD0SAYBABAy2Voak41PV3e3FIvlx2IxHw9Hh+EX9ksa9vMLO14/ACg9kkEAAITM2rXS9dcfmgnU1OTb5SgeLfkCrpmMr99h5reZTBkLu1a8w/AL+yUN+/mFHa8fAJQeNYMAAAAAAABCiJpBAAAAGFfhLwhr4ReGAACgPMqSDDKzqJkNmNnG0T+nlaMfAADqRRD4xyNHIn4bBNUeUf16cs6TenXZq3pv13vVHkporOzt1YqenoMJIOecVvT0aGVvb5VHhknjLxkAQBHKNTPoE5IedM51jP75dZn6AQCg5gWBL97c3+8fj9zf79t8Vpua/YP7tfve3frVSb8iKVQCzjntGR7WmsHBgwmhFT09WjM4qD3Dw8wQqgf8JQMAKFJZagaZ2TJJN0h6R9KvJV3nnBseb39qBgEAwiyZ9J/NCjU3S319lR5N/dtoGw9+bUeZLGL60DUfUvLWpI4+8ejqDayO5SaAsjrjca1qaZGZVXFkmBT+kgEAjKPSNYOelvRZ59yZkmZI+vwYA0qb2TYz2/b666+XaRgAAFTfwEBxcUye2+808u6Idt29S8+e/2y1h1O3zEyrWlryYiSC6gh/yQAAilSuZNALzrldo19vkzS3cAfnXMY51+acazvhhBPKNAwAAKovkSgujsmzo0yRYyP647/4Y83/5fxqD6duZWcG5cqtIYQax18yAIAilSsZ9D0z+6SZNUn6j5KeL1M/AADUvO5uKRbLj8ViPo6pySaBTrz2RJ31r2fp5O+erKP/iCViU5G7RKwzHtfIwoXqjMfzagihxvGXDACgSNEyHfc2SQ9IMkn/7Jz7WZn6AQCg5qVSftvV5VdtJBL+M1o2juIcFT9KH/yTD6r51mYSQCVgZpodjebVCMouGZsdjbJUrB7wlwwAoEhlKSBdLApIAwAqzTmX9yG3sA00Gt4TAACET6ULSAMAULNW9vbmLX/JLpNZ2dtb5ZGhlgWBf2hTJOK3YXtq9wM3/FLJ6E5FbETJ6E49cMMvqz0k4JCwvwEBoMJIBgEAGopzTnuGh/PqoWTrpewZHqY+CsYUBFI67Z/e7ZzfptPh+TwaLNui9Lr56j8wR04R9R+Yo/S6+QqWban20IDwvwEBoApYJgYAaDi5CaCs3HopQKFk0n/+LNTcLPX1VXo0pZeM7lT/gTmHxZubdqpv+PA4UFFhfwMCQBmNt0yMZBAAoCE55xR54omD7ZGFC0kEYVyRiJ+QUMhMGhmp/HhKLWIjcmNMGDeNaMQxkRxVFvY3IACUETWDAAAYlZ0ZlItHaONIEoni4vUm0fSbouJARYX9DQgAVUAyCADQUHKXiHXG4xpZuFCd8XheDSGgUHe3FIvlx2IxHw+D7nSfYnonLxbTO+pO91VnQECusL8BAaAKSAYBABqKmWl2NJpXI2hVS4s643HNjkZZKoYxpVJSJuNLlJj5bSbj42GQWnu+Mtc/q+amnTKNqLlppzLXP6vU2vOrPTQg/G9AAKgCagYBABqScy4v8VPYBgAAAOodNYMAAMhRmPghETRNQeCf+BOJ+G2ZH/lc4e6qohHOEXWMGxQA6lq02gMAAAB1LgikdFoaGvLt/n7flsqyjKPC3VVFI5wj6hg3KADUPZaJAQCA6Ukm/YfBQs3NUl9fvXdXFY1wjqhj3KAAUDfGWyZGMggAAExPJCKN9f8JM2lkpN67q4pGOEfUMW5QAKgb1AwCAADlkUgUF6+v7qqiEc4RdYwbFADqHskgAAAwPd3dUiyWH4vFfLz+u6uKRjhH1DFuUACoeySDAADA9KRSUibj64WY+W0mU7ZCshXurioa4RxRx7hBAaDuUTMIAAAAAAAghKgZBAAAAIRU4S94a+EXvvWM6wkg7EgGAQAATMayZVI06pfFRKO+HSZB4B8ZHon4bRBUe0SYpJW9vVrR03MwYeGc04qeHq3s7a3yyOoT1xNAIyAZBAAAMJFly6R166QDB3z7wAHfDktCKAikdFrq7/ePDO/v920SQjXPOac9w8NaMzh4MIGxoqdHawYHtWd4mBktReJ6AmgU1AwCAACYSDR6KBGUq6lJGh6u/HhKLZn0CaBCzc1SX1+lR4Mi5SYssjrjca1qaZGZVXFk9YnrCSBMqBkEAAAwVWMlgo4UrzcDA8XFUVPMTKtaWvJiJC6mjusJoBGQDAIAAJhIU1Nx8XqTSBQXR03JzmTJlVvzBsXhegJoBCSDAAAAJpJOFxevN93dUiyWH4vFfBw1LXdJU2c8rpGFC9UZj+fVvMHkcT0BNIpotQcAAABQ89au9dtMxi8Na2ryiaBsvN6lUn7b1eWXhiUSPhGUjaNmmZlmR6N5NW2yS5xmR6MsbSoS1xNAo6CANAAAAFDnnHN5iYrCNorD9QQQFhSQBgAAmI4g8E/dikT8lseu15dKv34V7q8wUUHiYnq4ngDCjmViAAAAEwkCvyxsaMi3+/sP1QtiKVXtq/Trx/0CAKhxLBMDAACYSDLpP9AXam6W+voqPRoUq9KvH/cLAKBGsEwMAABgqgYGioujtlT69eN+AQDUOJJBAAAAE0kkioujtlT69eN+AQDUOJJBAAAAE+nulmKx/Fgs5uOofZV+/bhfAAA1jmQQAADARFIpKZPxNV/M/DaToRhwvaj068f9AgCocRSQBgAAAAAACCEKSANQEPgHnEQifhsE1R4RalrYb5hKn1/Yr2elLVsmRaN+1kU06tthE/Z7JuznBwBADYtWewAAKiMIpHRaGhry7f5+35aYtY4xhP2GqfT5hf16VtqyZdK6dYfaBw4caq9dW50xlVrY75mwnx8AADWOZWJAg0gm/f+1CzU3S319lR4Nal7Yb5hKn1/Yr2elRaM+AVSoqUkaHq78eMoh7PdM2M8PAIAaMd4yMZJBQIOIRKSx3u5m0shI5ceDGhf2G6bS5xf261lpZuN/rwb+X1MSYb9nwn5+AADUCGoGAQ0ukSgujgYX9hum0ucX9utZaU1NxcXrUdjvmbCfHwAANY5kENAgurulWCw/Fov5OHCYsN8wlT6/sF/PSsvWlplsvB6F/Z4J+/kBAFDjSAYBDSKVkjIZX47BzG8zGep0Yhxhv2EqfX5hv56VtnatdP31h2YCNTX5dliKR0vhv2fCfn4AANQ4agYBAAAAAACEEDWDAAC1LQj8E4YiEb8NgmqPCGgsvAdLq9LXk9cPAFCEaLUHAACAgsDXexka8u3+/kP1X1g2ApQf78HSqvT15PUDABSJZWIAgOpLJv2Hl0LNzVJfX6VHAzQe3oOlVenryesHABjHeMvESAYBAKovEpHG+vfITBoZqfx4gEbDe7C0Kn09ef0AAOOgZhAAoHYlEsXFAZQW78HSqvT15PUDABSJZBAAoPq6u6VYLD8Wi/k4gPLjPVhalb6evH4AgCKRDAIAVF8qJWUyvr6Fmd9mMhQ+BSqF92BpVfp68voBAIpEzSAAAAAAAIAQomYQAABAHSn8hV0t/AIPAACEA8kgAACAGrOyt1crenoOJoCcc1rR06OVvb1VHlkJBYF/JHok4rdBUO0RAQDQMEgGAQAA1BDnnPYMD2vN4ODBhNCKnh6tGRzUnuHhcMwQCgIpnZb6+/0j0fv7fZuEEAAAFUHNIAAAgBqTmwDK6ozHtaqlRWZWxZGVSDLpE0CFmpulvr5KjwYAgNCiZhAAAECdMDOtamnJi4UmESRJAwPFxQEAQEmRDAIAAKgx2ZlBuXJrCNW9RKK4OAAAKCmSQQAAADUkd4lYZzyukYUL1RmP59UQqnvd3VIslh+LxXwcAACUXbTaAwAAAMAhZqbZ0WhejaDskrHZ0Wg4loqlUn7b1eWXhiUSPhGUjQMAgLKigDQAoCE55/I+VBe2670/1D/uGQAAMF0UkAYAYNTK3t685TbZZTkre3vL19+PfyyXTEqRiFwyqRU//nHZ+quKIPBPiIpE/JZHhE9bYeKHRBAAACgVkkEAgIbinNOe4eG8+ivZ+ix7hodLXo/FOac9L72kNbNmacWiRb6/RYu0ZtYs7XnppXDUfwkCKZ32jwp3zm/TaRJCAAAANYplYgCAhpObAMrKrc9S8v6SSZ8AWrLkUH8PP6xVP/qRrK+v5P1VXDLpE0CFmpulMJwfAABAnRpvmRjJIABAQ3LOKfLEEwfbIwsXlm8ZTiTi+/vFLw719+lP+/5GRsrTZyVFIn5GUKGwnB8AAECdomYQAACjsjODcpXzkd0ukdCKG27I7++GG+QSibL0V3HjnUdYzg8AACBkSAYBABpK7hKxznhcIwsXqjMez6shVPL+vvMdrVmyRJ0PP6yRT39anQ8/rDVLlmjFd74TjppB3d1SLJYfi8V8HAAAADVnWskgM/t0qQYCAEAlmJlmR6N5NYJWtbSoMx7X7Gi05EvFzEyz581T5969vkaQmVb96Efq3LtXs+fNC8cTolIpKZPxNYLM/DaT8XEAAADUnCPWDDKzJkkPSfpTSQ875/7EzCLOuZHR7292zl0w3UFQMwgAUGnOubxETGG73vsDAAAAplQzyDl3QNIxkm6VNNfM/quk75nZYjM7VtKusowWAIAyswce8E/BikSkZNK3Q9SfgiCvPx7zDgAAgKzoJPYZkfSEpE9L+qikmKSPS/pPkh4v39AAACiTIJDSaWloyLf7+31bKs/SprD3BwAAgLoy7jIxM5sh6UeS3nPOfcnMfiDpaUltkpaPfv0F59y013exTAwAUFHJpE+QFGpulvr66A8AAAChUPQyMefc+5L+0v+s3S9pgaQLJR0tKSPpq5IuK89wAQAoo4GB4uL0BwAAgBCZqGbQq5KcpL+W9Kp8Aigq6UvOuR9JOqnsIwQAoNQSieLi9AcAAIAQmcyj5WfKF5HeLGmfpFudc/tHv/dWuQYGAEDZdHdLsVh+LBbzcfoDAABAyE2mgHSfpBXyiaP/Iek4M5slaaeku8o3NAAAyiRbRLmryy+dSiR8oqRcxZXD3h8AAADqyrgFpCf8QbNTJSWdc49MdxAUkAYAAAAAACitogtIj3GACwtC/1aKRBAAAJI0MjJyxDZQbYW/QJvqL9QAAACqbdLJIEl/k/3CzI6VtHV0Oy4z+5CZPTvVwQEAGkPHs8/qjO3bDyaARkZGdMb27ep4ln9CpiwI/CPmIxG/DYJqj6i0Knx+K3t7taKn52ACyDmnFT09WtnbW9Z+AQAAyuGIySAzW5TT3J/z9Xck/dA5t2+C4/+tpCMmjAAAjW1kZES/Hx7Wc++8czAhdMb27XrunXf0++FhZghNRRBI6bTU3y8557fpdHgSQhU+P+ec9gwPa83g4MGE0IqeHq0ZHNSe4WFmCAEAgLpzxJpBZrZG0h7n3DfM7HFJl0r6fyTNkHS9c27c/6GPLiv7T5JOcc51HGkQ1AwCgMaWmwDKOn3mTG0/4wxFIsVMYoUkP1Omv//weHOz1NdX6dGUXhXOLzcBlNUZj2tVS4vMrCx9AgAATNd4NYMmLCBtZn8n6VlJfy4/k+g+Sb+T9E9unB82s6MkbZB0mfwMoo4x9klLSktSIpE4o3+s/9QBABrGyMiImjZtOtg+0N5OImiqIhE/Y6aQmRSGmVZVOj/nnCJPPHGwPbJwIYkgAABQ06ZTQPovJZ0sadg5d65z7h5JX5C09Ag/c7Oktc65PePt4JzLOOfanHNtJ5xwwiSGAQAIq+zMoFy5NYRQpESiuHi9qcL5ZWcG5cqtIQQAAFBPJqoZ9DeSbpW0T1LCzL5uZl+X9O+Svm1mp4zzo5+VdIOZbZR0upndU8IxAwBCJHeJ2OkzZ+pAe7tOnzkzr4YQitTdLcVi+bFYzMfDoMLnl7tErDMe18jCheqMx/NqCAEAANST6ATff0rSgdGvF0v6Vc73eiTtHeuHnHPt2a/NbKNz7trpDBIAEF6RSETHRaN5NYK2n3GGzti+XcdFoywVm4pUym+7uqSBAT9jprv7ULzeVfj8zEyzo9G8GkGrWlokSbOjUZaKAQCAujNhzaCDO5ptcc6dX45BUEAaQD1yzuV9CCxsozgjIyN5iZ/Cdqnx+qFY3DMAAKDeTKdmUNadJRwPANS1lb29ectDsstIVvb2Vnlk9asw8VPORFBDvH5B4J+6FYn4bVgeK19FhYkfEkEAAKBeTfg/bTO7xsxmSHrYzC4ajV1a9pEBQI1yzmnP8HBevZBsPZE9w8PUD6lxDfH6BYGUTvvHrzvnt+k0CSEAAABImmCZmJl1SPqGpCclzZJ0jqSbJK2Rf8pY1Dn3+HQHwTIxAPUmN4GQlVtPBLUt9K9fMukTQIWam6W+vkqPBgAAAFVS9DIxMztd0hmjzX+R9JqkYyUlJR0j/7j5stQQAoBal1tANis0iYQGEPrXb2CguDgAAAAayrjJIOfcc5KekPRTSSbpIUmPSvo3Sc9LOlvSLyowRgCoOdmZJbl4xHT9CP3rl0gUFwcAAEBDmahm0F9Kmi3p85K+KulVSUdJ+i+S3pY0s6yjA4AalLvEqDMe18jCheqMx/Nq0KB2NcTr190txWL5sVjMxwEAANDwohN8f4OkL8onfpokNUs6RdInJb0jnygCgIZiZpodjebVmMkuOZodjYZnqVFINcTrl0r5bVeXXxqWSPhEUDYOAACAhjZRAek5klZJellSr6SLJPVL+rik30h6wDm3ebqDoIA0gHrknMtLHBS2Udt4/QAAABB2RReQHvUhSTFJ/1vSuZLmSuqTTwh9TX52EAA0pMLEAYmEaQoC/xSsSMRvy/wYdF4/AAAANKpxl4mZ2cclnS7JydcK2i//dLGYpJPkHy/fK+mZ8g8TABBqQSCl09LQkG/39/u2xNImAAAAoMTGTQY553ZI2mFm++SXif1C0uuStkjaJCku6Y1KDBIAEHJdXYcSQVlDQz5OMggAAAAoqYmWiUnSV5xzOyX9maQ+59zrzrntktok/UVZRwcAaAwDA8XFAQAAAEzZZJJB749ufyXpTjM7XpKcc1+XrykEAMD0JBLFxQEAAABM2bjJIDObaWb3SDrNzP6LpGFJ35Z0j5klzOw0SSMVGicAIMy6u6VYLD8Wi/k4AAAAgJIat2aQpH2SviP/BLGnJH1dvoj0TEnfly8cvbbcAwQANIBsXaCuLr80LJHwiSDqBQEAAAAlZ865I+9g9s/OuS+ZWcQ5N2JmMUk/ldTunDtQikG0tbW5bdu2leJQAAAAAAAAkGRm251zbYXxI80Mkpm9JOlEM7tP0h+YWefot+6U9GEzm+Gce630wwUAAAAAAEA5HLGAtHNunqRfOuf+XH5p2MuSviHps5K6JN1a9hECABpDEEjJpBSJ+G0QVHtEAAAAQCgdcWbQqKMkyTn3vdElYh91zv238g4LANBQgkBKp6WhId/u7/dtibpBAAAAQIlN5tHyq7JfOOfulvR4+YYDAGhIXV2HEkFZQ0M+DgAAAKCkJkwGOecePVIbAIBpGxgoLg4AAABgyiYzMwgAgPJKJIqLAwAAAJgykkEAgOrr7pZisfxYLObjAAAAAEqKZBAAoPpSKSmTkZqbJTO/zWQoHg0AAACUwWSeJgYAQPmlUiR/AAAAgApgZhAAoDEFgZRMSpGI3wZBtUcEAAAAVAQzgwAAjScIpHT60OPs+/t9W2J2EgAAAEKPmUEAgMbT1XUoEZQ1NOTjAAAAQMiRDAIANJ6BgeLiAAAAQIiQDAIANJ5Eorg4AAAAECIkgwAAjae7W4rF8mOxmI8DAAAAIUcyCADQeFIpKZORmpslM7/NZCgeDQAAgIbA08QAAI0plSL5AwAAgIbEzCAA5RMEUjIpRSJ+GwTVHhFQPbwfAAAAUCOYGQSgPIJASqcPPb67v9+3JWZjoPHwfgAAAEANMedctcegtrY2t23btmoPA0ApJZP+A2+h5mapr6/SowGqi/cDAAAAqsDMtv//7d1/cJ3ZXR/gz5HkEESCdiFLGBykm8QZSsDQZjVhoYHd1EvzY2NgCu22VUnboSNq7cAmLR3ouIS1Qf2DgcThhz2ohDbADVACpXVMJjRuQ+iENNEmFENKBye2lOwQ2FBWkLhJ1vbpH1dWJK2s1V3r3ivd93lmNNL93nd1zvvec1/rfva85621Tm+uu0wM6I3l5e7qMMy8HwAA2EOEQUBvTE52V4dh5v0AAMAeIgwCemN+Phkf31gbH+/UoWm8HwAA2EOEQUBvzMwkCwudNVFK6XxfWLBYLs3k/QAAwB5iAWkAAACAIWQBaQAAAACEQQAAAABNIgwCAAAAaBBhEAAAAECDCIMAAAAAGkQYBAAAANAgwiAAAACABhEGAQAAADSIMAgAAACgQYRB0CTtdtJqJSMjne/t9nC1BwAAwJMaG3QHgD5pt5PZ2eTKlc7jpaXO4ySZmdn/7QEAALAjpdY66D5kenq6Li4uDrobMNxarU4gs9nUVHL58v5vDwAAgA1KKQ/XWqc3110mBk2xvNxdfb+1BwAAwI4Ig6ApJie7q++39gAAANgRYRA0xfx8Mj6+sTY+3qkPQ3sAAADsiDAImmJmJllY6KzZU0rn+8JC7xZz7nd7AAAA7IgFpAEAAACGkAWkAQAAABAGAQAAADSJMAgAAACgQYRBAAAAAA0iDAIAAABoEGEQAAAAQIMIgwAAAAAaRBgEAAAA0CDCIAAAAIAGEQYBAAAANIgwCAAAAKBBhEEAAAAADSIMAgAAAGgQYRAAAABAgwiDAAAAABpEGAQAAADQID0Lg0opX1RK+eZSyrN61QYAAAAA3elJGFRKuT3J25K8OMl/L6Xc0Yt2ADZot5NWKxkZ6XxvtwfdIwAAgD1nrEe/92uS/Ita63tXg6EXJXlHj9oC6AQ/s7PJlSudx0tLncdJMjMzuH4BAADsMT2ZGVRr/e3VIOib0pkd9Lu9aAdgzfHjnwuCbrhypVMHAABgTS/XDCpJ7k/yF0ke3+L52VLKYill8dFHH+1VN4CmWF7urg4AANBQPQuDascDSX4/ybds8fxCrXW61jp9xx2WFAJu0eRkd3UAAICG6tUC0t9fSnn16sPbkjzWi3YA1szPJ+PjG2vj4506AAAAa3o1M2ghyXeWUt6dZDTJb/WoHYCOmZlkYSGZmkpK6XxfWLB4NAAAwCal1jroPmR6p4EMIwAAGnNJREFUerouLi4OuhsAAAAAQ6OU8nCtdXpzvWdrBgEAAACw9wiDAAAAABpEGAQAAADQIMIgAAAAgAYRBgEAAAA0iDAIAAAAoEGEQQAAAAANIgwCAAAAaBBhEAAAAECDCIMAAAAAGkQYBAAAANAgwiAAAACABhEGAQAAADSIMAgAAACgQYRBAAAAAA0iDAIAAABoEGEQAAAAQIMIgwAAAAAaRBgEAAAA0CDCIAAAAIAGEQYBAAAANIgwCAAAAKBBhEEAAAAADSIMAgAAAGgQYRAAAABAgwiDAAAAABpEGAQAAADQIMIgAAAAgAYRBgEAAAA0iDAIAAAAoEGEQQAAAAANIgwCAAAAaBBhEAAAAECDCIMAAAAAGkQYBAAAANAgwiAAAACABhEGAQAAADSIMAgAAACgQYRBAAAAAA0iDAIAAABoEGEQAAAAQIMIgwAAAAAaRBgEAAAA0CDCIAAAAIAGEQYBAAAANIgwCAAAAKBBhEEAAAAADSIMAgAAAGgQYRAAAABAgwiDAAAAABpEGAQAAADQIMIgAAAAgAYRBgEAAAA0iDAIAAAAoEGEQQAAAAANIgwCAAAAaBBhEAAAAECDCIMAAAAAGkQYBAAAANAgwiAAAACABhEGAQAAADSIMAgAAACgQYRBAAAAAA0iDAIAAABoEGEQAAAAQIMIgwAAAAAaRBgEAAAA0CDCIAAAAIAGEQYBAAAANIgwCAAAAKBBhEEAAAAADSIMAgAAAGgQYRAAAABAgwiDAAAAABpEGAQAAADQIMIgAAAAgAYZ68UvLaVMJPnlJKNJPpXk/lrrZ3vRFgAAAAA716uZQTNJXl9r/dtJPp7k5T1qBwAAAIAu9GRmUK319LqHdyT5s83blFJmk8wmyeTkZC+6AQAAAMAmPV0zqJTy9Ulur7W+d/NztdaFWut0rXX6jjvu6GU3AAAAAFjVk5lBSVJK+aIkP5nk23vVBgAAAADd6cnMoFLK05L8apJ/XWtd6kUbAAAAAHSvV5eJfVeSFyU5Xkp5Vynl/h61AwAAAEAXerWA9JkkZ3rxuwEAAAB46nq6gDSwvfaFdlqnWhk5MZLWqVbaF9qD7tK+5ngCAAA8uZ4tIA1sr32hndmzs7ny+JUkydLKUmbPziZJZg7PDLJr+5LjCQAAsDNmBsGAHD9/fC24uOHK41dy/PzxAfVof3M8AQAAdkYYBAOyvLLcVZ3tOZ4AAAA7IwyCAZmcmOyqzvYcTwAAgJ0RBsGAzB+Zz/iB8Q218QPjmT8yP6Ae7W+OJwAAwM4Ig2BAZg7PZOHoQqYmplJSMjUxlYWjCxY7foocTwAAgJ0ptdZB9yHT09N1cXFx0N0AAAAAGBqllIdrrdOb62YGAQAAADSIMAgAAACgQYRBAAAAAA0iDAIAAABoEGEQAAAAQIMIgwAAAAAaRBgEAAAA0CDCIAAAAIAGEQYBQ6N9oZ3WqVZGToykdaqV9oX2oLu0r82dm8vYybGUEyVjJ8cyd25u0F3a14xPAAD2irFBdwBgN7QvtDN7djZXHr+SJFlaWcrs2dkkyczhmUF2bV+aOzeXM4tn1h5fq9fWHp++7/SgurVvGZ8AAOwlpdY66D5kenq6Li4uDrobwD7WOtXK0srSE+pTE1O5/JrL/e/QPjd2cizX6rUn1EfLaK6+7uoAerS/GZ8AAAxCKeXhWuv05rrLxIChsLyy3FWd7W0VBG1XZ3vGJwAAe4kwCBgKkxOTXdXZ3mgZ7arO9oxPAAD2EmEQMBTmj8xn/MD4htr4gfHMH5kfUI/2t9k7Z7uqsz3jEwCAvUQYBAyFmcMzWTi6kKmJqZSUTE1MZeHogsV5n6LT953OseljazOBRstojk0fs3j0U2R8AgCwl1hAGgAAAGAIWUAaGHqbw+29EHYDAADsNcIgWNW+0E7rVCsjJ0bSOtVK+0K7523OnZvL2MmxlBMlYyfHMndurudt9tO9P39vyomy9nXvz9/bs7YeunQpr714cS0AqrXmtRcv5qFLl3rWJgAAwH4kDIJ0gqDZs7NZWllKTc3SylJmz872NBCaOzeXM4tn1m7Vfa1ey5nFM0MTCN378/fm/KXzG2rnL53vSSBUa81jV6/mjY88shYIvfbixbzxkUfy2NWrZggBAACsY80gSNI61crSytIT6lMTU7n8mss9aXPs5NhaELTeaBnN1ddd7Umb/VROlJs+V39o98876wOgGx48eDBvOHQopdy8LwAAAMPKmkGwjeWV5a7qu2GrIGi7OtsrpeQNhw5tqAmCAAAAnkgYBEkmJya7qu+GG7fs3mmd7d2YGbTe+jWEAAAA6BAGQZL5I/MZPzC+oTZ+YDzzR+Z71ubsnbNd1febI8890lX9Vqy/ROzBgwdz/e678+DBgxvWEAIAAKBDGARJZg7PZOHoQqYmplJSMjUxlYWjC5k5PNOzNk/fdzrHpo+tzQQaLaM5Nn0sp+873bM2++mdr37nE4KfI889kne++p273lYpJbeNjW1YI+gNhw7lwYMHc9vYmEvFAAAA1rGANHtWrXXDh/jNj+nesB/Ta9euZXR09KaPAQAAmsQC0uwrD126tOHynhuXAT106dKAe7Z/DeKYti+00zrVysiJkbROtdK+0O5ZW/d88IN53nvOZ3K1vclTrTzvPedzzwc/2LM2587NZezkWMqJkrGTY5k7N9eztpL+Hs+k//s37Pr9+gEAwM0Ig9hzaq157OrVDeu93FgP5rGrV63/8hQM4pi2L7Qze3Y2SytLqalZWlnK7NnZnnwAvn79ei598tEsX3taPvr846mp+ejzj2f52tNy6ZOP5vr167ve5ty5uZxZPLN297dr9VrOLJ7pWWDSz+OZ9H//hl2/Xz8AANiOy8TYk9aHFTesXw+G7vX7mLZOtbK0svSE+tTEVC6/5vKutzd5qpWPPv948swXfK74V3+cL//wfJZ70N7YybG1oGS90TKaq6+7uuvt9ft49nv/hl2/Xz8AAEhcJsY+c2MB4PUEQbem38d0eWW5q/qt+tjKcvKBTXdi+8Bsp94DWwUl29VvVb+PZ7/3b9j1+/UDAIDtCIPYk27MYlnPLcJvTb+P6eTEZFf1W/WcicnkRQsbiy9a6NR74MZd4HZav1X9Pp793r9h1+/XDwAAtiMMYs9ZfznTgwcP5vrdd+fBgwc3rHdDdwZxTOePzGf8wPiG2viB8cwfmd/1tq5fv55y50LnErG/+uPkt1/a+f7MF6TcudCTNYNm75ztqn6r+nk8k/7v37Dr9+sHAADbGRt0B2CzUkpuGxvbsJ7Njcubbhsbc6nYUzCIYzpzeCZJcvz88SyvLGdyYjLzR+bX6rtpZGQkz33GHcknH0398Hw+lpLnfHg+5c6FPPcZd2RkZPdz79P3nU6SLDy8kGv1WkbLaGbvnF2r77Z+Hs+k//s37Pr9+gEAwHYsIM2edf369Q0f4jc/pnu11g3Bz+bH+921a9cyOjp608cAAABNYgHpIdS+0E7rVCsjJ0bSOtUaqlsUP3TpUl75vt/M1Or+TZ1q5ZXv+808dOnSoLu2q+bOzWXs5FjKiZKxk2M9v233W/7gLRvGzFv+4C09ba+f+/fQpUu57/1v3zBm7nv/23s6Zob5PTgIjicAAPSHy8T2qfaFdmbPzubK41eSJEsrS5k921nLY79fdlBrzXv/9A/zjk8/I3nWq5KVn87ys16V5U8/I/nTP0xttYZiNsvcubmcWTyz9vhavbb2uBeX4vR7zPRz/wYxZob5PTgIjicAAPSPy8T2qdapVpZWlp5Qn5qYyuXXXO5/h3bZ1KlWlp/1quQ53/G54sfemslPvC1LQ7B/STJ2cmzL23SPltFcfd3VXW+v32Om3/vX7zEz7O/BfnM8AQBg97lMbMgsryx3Vd9vPrqynHz4pzcWP/zTnfqQ2Coo2a5+q/o9Zvq9f/0eM8P+Huw3xxMAAPpHGLRPTU5MdlXfb758YjJ5/gMbi89/oFMfEqNl64WNb1a/Vf0eM/3ev36PmWF/D/ab4wkAAP0jDNqn5o/MZ/zA+Iba+IHxzB+ZH1CPdk+tNV951091Lvf52FuT335p5/tzviNfeddPZS9c2rgbZu+c7ap+q/o9Zvq5f4MYM8P8HhwExxMAAPpHGLRPzRyeycLRhUxNTKWkZGpiKgtHF4ZiodVSSu569lflZU//ZCY/8baUlEx+4m152dM/mbue/VVDsXh00llE+dj0sbWZMqNlNMemj/Vk8eik/2Omn/s3iDEzzO/BQXA8AQCgfywgzY7VWjd8qN78eL+3x/5nzAAAAHyOBaSH0Ny5uYydHEs5UTJ2cixz5+Z61tZDly7ltRcvrl1uU2vNay9ezEOXLvWszc0f4nv9ob59oZ3WqVZGToykdaqV9oV2T9trgn4f036PmWHX79fPexAAAPpjbNAd4KmZOzeXM4tn1h5fq9fWHu/2ZTi11jx29Wre+MgjSZI3HDqU1168mDc+8kgePHhwKGZftC+0M3t2Nlcev5IkWVpZyuzZzto2LlN5ahzT/a3fr5/xAgAA/eMysX1q7OTYlrfoHi2jufq6q7ve3o2ZQDcCoSR58ODBvOHQoX0fBCVJ61QrSytLT6hPTUzl8msu979DQ8Ax3d/6/foZLwAAsPtcJjZktgqCtqvfqlJK3nDo0IbasARBSbK8stxVnSfnmO5v/X79jBcAAOgfYdA+deMOTTut36obM4PWW7+G0H43OTHZVZ0n55jub/1+/YwXAADoH2HQPjV752xX9Vux/hKxBw8ezPW7786DBw/mjY88MjSB0PyR+YwfGN9QGz8wnvkj8wPq0f7nmO5v/X79jBcAAOgfYdA+dfq+0zk2fWxtJtBoGc2x6WO7vnh00rlE7LaxsQ1rBL3h0KE8ePBgbhsbG4pLxWYOz2Th6EKmJqZSUjI1MZWFowsWrr0Fjun+1u/Xz3gBAID+sYA0O7b5rmHDcBcxAAAAGFYWkOaWbQ5+BEEAAACw/wiDgJ5pX2indaqVkRMjaZ1qpX2hPeguQWN4/wEAcDNjg+4AMJzaF9qZPTubK49fSZIsrSxl9mxngXPrwEBvef8BALAdM4OAnjh+/vjaB9Ebrjx+JcfPHx9Qj6A5vP8AANiOMAjoieWV5a7qwO7x/gMAYDvCIKAnJicmu6oDu8f7DwCA7QiDgJ6YPzKf8QPjG2rjB8Yzf2R+QD2C5vD+AwBgO8IgoCdmDs9k4ehCpiamUlIyNTGVhaMLFq+FPvD+AwBgO6XWOug+ZHp6ui4uLg66GwAAAABDo5TycK11enPdzKBd1L7QTutUKyMnRtI61Ur7QnvQXQIAAADYYGzQHRgW7QvtzJ6dXbuV79LKUmbPziaJafkAAADAnmFm0C45fv74WhB0w5XHr+T4+eMD6hEAAADAEwmDdsnyynJXdQAAAIBBEAbtksmJya7qAAAAAIMgDNol80fmM35gfENt/MB45o/MD6hHAAAAAE8kDNolM4dnsnB0IVMTUykpmZqYysLRBYtHAwAAAHtKqbUOug+Znp6ui4uLg+4GAAAAwNAopTxca53eXDcziD2rfaGd1qlWRk6MpHWqlfaF9qC7BAAAAPteT8OgUsqzSym/08s2GE7tC+3Mnp3N0spSamqWVpYye3ZWIAQAAAC3qGdhUCnl9iRvTvIFvWqD4XX8/PFcefzKhtqVx6/k+PnjA+oRAAAADIdezgy6luT+JH+51ZOllNlSymIpZfHRRx/tYTfYj5ZXlruqAwAAADvTszCo1vqXtdaVbZ5fqLVO11qn77jjjl51g31qcmKyqzoAAACwMxaQZk+aPzKf8QPjG2rjB8Yzf2R+QD0CAACA4SAMYk+aOTyThaMLmZqYSknJ1MRUFo4uZObwzKC7BgAAAPva2KA7ADczc3hG+AMAAAC7rOczg2qt9/S6DQAAAAB2xmViAAAAAA0iDAIAAABoEGEQAAAAQIMIgwAAAAAaRBgEAAAA0CDCIAAAAIAGEQYBAAAANIgwCAAAAKBBhEEAAAAADSIMAgAAAGgQYRAAAABAgwiDAAAAABpEGAQAAADQIMIgAAAAgAYRBgEAAAA0iDAIAAAAoEGEQQAAAAANIgwCAAAAaBBhEAAAAECDCIMAAAAAGqTUWgfdh5RSHk2yNOh+sGPPSvKJQXeCfcWYoRvGC90wXuiWMUM3jBe6ZczQjX6Ml6la6x2bi3siDGJ/KaUs1lqnB90P9g9jhm4YL3TDeKFbxgzdMF7oljFDNwY5XlwmBgAAANAgwiAAAACABhEG8VQsDLoD7DvGDN0wXuiG8UK3jBm6YbzQLWOGbgxsvFgzCAAAAKBBzAwCAAAAaBBhEAAAAECDCIPYVinl2aWUD97kubFSynIp5V2rX4f73T9gf9rp+aOU8nvrtvnmfvcT2N9KKadLKUdv8py/Y4CulVKOrTtv/F4p5We22Mb5hT1vbNAdYM/7sSSff5PnvibJL9Vav7+P/WEPKqWMJfnI6leSfE+t9cIW251I8sok76u1PtDHLrL3POn5o5TyxUn+qNb69/vXLfayUsrpJG+vtZ69yfNvSvLCJOdqrT/S186x55RSvjHJl95svMTfMawqpRxLcv/qw9uS/M9a63dvsZ1zDKm1nklyJklKKT+Z5M1bbOb8wppSyu1J2km+JMnDW51fVrfr6znGzCBuqpTyt5J8KsnHb7LJXUleVUp5XynlTauBAM104x+8e1a/tgqC7kzykiQvTvJnpZR7+91J9pSdnD++LsmLSynvKaX8RinlmX3uI3vIk32wL6X8nSSjtdavT/K8UsoL+tpB9pRSyoEk/y7J5VLKt95kM3/HkKTz4f7G3zBJfiedsbOBcwyblVIOJnl2rXVxi6edX1jvO5O0a63TSZ5ZSpnevMEgzjHCILZUSnlakh9M8gPbbPb+JPfWWl+c5EA6Mz5opp38g3d3kl+rnVsYviPJN/a1h+w1Ozl/fCTJy2qt35Dk95P80z72jz1khx/s70nyH1d//q10wmea69VJPpTkR9MJlb9ni238HcMGT/Lh/p44x7DRA1mdIbQF5xfW+/MkX11KuS3Jlyf56Bbb3JM+n2OEQdzMDyQ5XWt9bJttfr/W+ierPy8m8X9Immsn/+B9QZJHVn/+v0me3ae+sTft5PzxkSQXn2QbmmEnH+ydY1jvbyRZqLV+PMkvJnnpFtv4O4bNtvtw7xzDmlLKSDrnlXfdZBPnF9b7H0mmknxvkv+dzjlks76fY4RB3My9SR4opbwryV8vpfzsFtv8Qinla0spo0m+Lcn/6mcH2VN28g/eJ/O59aeeEeefptvJ+WM+yY2FX7/jJtvQDDv5YO8cw3oXkzxv9efpJEtbbOPvGNbs4MO9cwzrfWM6a0vVmzzv/MJ6P5Tkn9daTyb5o2w9273v5xgnMbZUa/2mdddO/16S15dSNi9idTLJL6w+/7u11nf2uZvsHTv5B+/hfG6649cmudynvrE3bTh/JPnAFqHz65McL6X8QZLPZOsFGmmGnXywd45hvTcleWkp5d1J5pK81d8xPIkn+3DvHMN6L0vy7iQppbzQ+YUncXuSw6uflb4uyVbnmb6fY8rNz3cAO1NK+eokb0lSkvyXJD+e5Edrrf9s3TYj6SzKuJjk5UleXmu9NIDuAvvM6uLhP5fOlOkDSb4vyStqrf9m3TZfmM455nySVyS5q9a6MoDuAvtQKeXfJlmstf56KeWFSf6hcwywG0opL07y79O5VOx3k/zLJH9v0OcYYRDQN6WUz09yX5IP1Fo/8mTbA3Rj9dat35zk3auXlAHsGucYoJf6fY4RBgEAAAA0iDWDAAAAABpEGAQAAADQIMIgAKBxSimjpZRnPMk2I6WUz9vFNp+2W78LAOBWCIMAgMYopXxo9cfDSd64rn5bKeUlpZS7SinvKKW8Msm3J/ml1drfLKV8ybrt71t/K+FSyk+UUr5lm3a/Isnb1j0e28XdAgDoij9EAIChVkp5RZLXJvlski8rpbwtyRcmmVr9+UCSX0zyl0muJflQkvF0/k66mORZ6fwPtKV1v/ZakqullJEkP5HksSRnN7X7c0mem+RTq6XPllLOrf6uzyT5tl3fWQCAHXA3MQCgMUop/6HW+k9KKdNJvqHW+hPrnptP55auV5L8vyT/Lck/SCck+nSt9eXrtn15kruSfH6SP661/uwWbS0kObX6ux6qtf7jUsq9Se5J8sO11s/0aDcBALZlZhAA0AillO9McnspZTTJ9yb54VLKX0vydbXWNyf5WJLfSvLJJF+a5ONJ/muSv1h9nFLK/av/7TPTmV20nOQlpZR/tNrM5yX5wVrrO9OZAfR3k7wkyVeUUn4jnVlGz0rytUmO9nynAQC2IAwCAIZeKeW705ml88Ja67VSymeTfGWS708n3EmStyb51XQu66pJDq3Wn57kXyVJrfVXkvzKuplBJ5O8J8mRWuunNzX79CQ/k+TNSd6UZDHJlyX5SK31x3qxnwAAOyEMAgCG2uqaQS9I8stJaillPMlUku9K8m211kdLKa0k35TkCZd7rTpcSkmt9YPri7XW66WUNyX58SQPbPpvJpK00gmMPpNkerV+eyllrNZ69Vb3DQDgqXA3MQBgqNVa315r/b50Fn2+K8k7k3xxkgdXg6CSzro+y+nMFnpuksubvj6aztpB602UUn42yZ8neVop5edWg6YbnlFrfW86l4ONJXkwycNJfk0QBAAMkjAIAGiS9yW5O8kH0lnzJ+nM3Lmr1vqudO4kdiTJj6z7+vUkj9ZaP7zu9zw/nZlFDyf5z0mOJfmTJIullC8spbwwySNJsrpQ9E8meX86t7T/zR7uHwDAk3I3MQCgEUopv5jOXbz+TynlW5PMJRlN8qdJHqi1PrZp+2cneUWS705yd631s+uem0xn5s+HNv03X1Br/VQp5b4kK0lmknxRko8k+U/pXCr20nTWDnpdrfV8b/YWAODmhEEAAFsopXxekvuTvKvWujzo/gAA7BZhEAAAAECDWDMIAAAAoEGEQQAAAAANIgwCAAAAaBBhEAAAAECD/H/HmkZzcMJh2AAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 1440x720 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# \"Iris-versicolor\":0,\"Iris-setosa\":1,\"Iris-virginica\":2\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "plt.figure(figsize=(20,10))\n",
    "mpl.rcParams[\"font.family\"] = 'SimHei' # 默认mpl不支持中文，设置一下支持 \n",
    "mpl.rcParams[\"axes.unicode_minus\"] = False # 设置中文字体是可以正常显示负号\n",
    "plt.scatter(x=t0[\"sepallength\"][:40], y=t0[\"petallength\"][:40], color='r', label=\"Iris-versicolor\")\n",
    "plt.scatter(x=t1[\"sepallength\"][:40], y=t1[\"petallength\"][:40], color='g', label=\"Iris-setosa\")\n",
    "plt.scatter(x=t2[\"sepallength\"][:40], y=t2[\"petallength\"][:40], color='b', label=\"Iris-virginica\")\n",
    "right = test_X[result == test_y]\n",
    "wrong = test_X[result != test_y]\n",
    "plt.scatter(x=right[\"sepallength\"], y=right[\"petallength\"], color='c', label=\"right\", marker=\"x\")\n",
    "plt.scatter(x=wrong[\"sepallength\"], y=wrong[\"petallength\"], color='m', label=\"wrong\", marker=\">\")\n",
    "plt.xlabel('花萼长度')\n",
    "plt.ylabel('花瓣长度')\n",
    "plt.title('KNN分类结果')\n",
    "plt.legend(loc='best')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
